#-*- coding: utf-8 -*-

import random

def binaryRandom(p):
    if random.random() < p:
        return 1
    else:
        return 0


def initialProbabilityVector(length):
    p = []
    for i in range(length):
        p.append(0.5)
    return p


def randomIndividual(pbb):
    x = []
    for i in range(len(pbb)):
        x.append(binaryRandom(pbb[i]))
    return x


def randomPopulation(pbb, size):
    x = []
    for i in range(size):
        x.append(randomIndividual(pbb))
    return x

def bestIndividual(population, function):
    best = population[0]
    bestVal = function(population[0])
    for i in range(1, len(population)):
        val = function(population[i])
        if val > bestVal:
            bestVal = val
            best = population[i]

    return best

def populationEval(population, fitFun):
    best = population[0]
    bestVal = fitFun(population[0])
    res = [[population[0], bestVal]]

    for i in range(1, len(population)):
        val = fitFun(population[i])
        res.append([population[i], val])
        if val > bestVal:
            bestVal = val
            best = population[i]

    return (best, bestVal, res)

def cross(*lists):
    """ iloczyn wektorowy """
    result = [[]]
    for oneList in lists:
        result = [elems+[elem] 
                    for elems in result 
                    for elem in oneList]
    return result

def fitnessProportionateSelector(fitnessList):
    """
    fitnessList zawiera rzeczywiste wartości 0..1 będące przeskalowaną
    funkcją celu osobnika.
    dodatkowo sum(fitnessList) = 1.

    Funkcja zwraca indeks losowego osobnika z ppb. wyboru danego osobnika
    równym jego wartości funkcji fitness
    """

    rand = random.random()

    prefixSum = 0
    for index, fitness in enumerate(fitnessList):
        if rand < prefixSum:
            return index-1
        prefixSum += fitness
    return index



if __name__ == "__main__":
    l = [0,0,0]

    for i in range(100000):
        l[fitnessProportionateSelector([0.1,0.4,0.5])] += 1

    l = [e/100000. for e in l]
    print(l)
